// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso;

import java.util.ArrayList;
import java.util.HashMap;
import se.krka.kahlua.j2se.KahluaTableImpl;
import se.krka.kahlua.vm.KahluaTable;
import se.krka.kahlua.vm.KahluaTableIterator;
import zombie.iso.areas.isoregion.IsoRegions;
import zombie.iso.sprite.IsoSprite;
import zombie.iso.sprite.IsoSpriteManager;
import zombie.vehicles.PolygonalMap2;

public class BentFences {
    private static final BentFences instance = new BentFences();
    private final ArrayList<BentFences.Entry> m_entries = new ArrayList();
    private final HashMap<String, ArrayList<BentFences.Entry>> m_bentMap = new HashMap();
    private final HashMap<String, ArrayList<BentFences.Entry>> m_unbentMap = new HashMap();

    public static BentFences getInstance() {
        return instance;
    }

    private void tableToTiles(KahluaTableImpl kahluaTableImpl, ArrayList<String> arrayList) {
        if (kahluaTableImpl != null) {
            KahluaTableIterator kahluaTableIterator = kahluaTableImpl.iterator();

            while (kahluaTableIterator.advance()) {
                arrayList.add(kahluaTableIterator.getValue().toString());
            }
        }
    }

    private void tableToTiles(KahluaTable kahluaTable, ArrayList<String> arrayList, String string) {
        this.tableToTiles((KahluaTableImpl)kahluaTable.rawget(string), arrayList);
    }

    public void addFenceTiles(int var1, KahluaTableImpl kahluaTableImpl0) {
        KahluaTableIterator kahluaTableIterator = kahluaTableImpl0.iterator();

        while (kahluaTableIterator.advance()) {
            KahluaTableImpl kahluaTableImpl1 = (KahluaTableImpl)kahluaTableIterator.getValue();
            BentFences.Entry entry = new BentFences.Entry();
            entry.dir = IsoDirections.valueOf(kahluaTableImpl1.rawgetStr("dir"));
            this.tableToTiles(kahluaTableImpl1, entry.unbent, "unbent");
            this.tableToTiles(kahluaTableImpl1, entry.bent, "bent");
            if (!entry.unbent.isEmpty() && entry.unbent.size() == entry.bent.size()) {
                this.m_entries.add(entry);

                for (String string0 : entry.unbent) {
                    ArrayList arrayList0 = (ArrayList)this.m_unbentMap.get(string0);
                    if (arrayList0 == null) {
                        arrayList0 = new ArrayList();
                        this.m_unbentMap.put(string0, arrayList0);
                    }

                    arrayList0.add(entry);
                }

                for (String string1 : entry.bent) {
                    ArrayList arrayList1 = (ArrayList)this.m_bentMap.get(string1);
                    if (arrayList1 == null) {
                        arrayList1 = new ArrayList();
                        this.m_bentMap.put(string1, arrayList1);
                    }

                    arrayList1.add(entry);
                }
            }
        }
    }

    public boolean isBentObject(IsoObject obj) {
        return this.getEntryForObject(obj, null) != null;
    }

    public boolean isUnbentObject(IsoObject obj) {
        return this.getEntryForObject(obj, IsoDirections.Max) != null;
    }

    private BentFences.Entry getEntryForObject(IsoObject isoObject, IsoDirections isoDirections) {
        if (isoObject != null && isoObject.sprite != null && isoObject.sprite.name != null) {
            boolean _boolean = isoDirections != null;
            ArrayList arrayList = _boolean ? (ArrayList)this.m_unbentMap.get(isoObject.sprite.name) : (ArrayList)this.m_bentMap.get(isoObject.sprite.name);
            if (arrayList != null) {
                for (int _int = 0; _int < arrayList.size(); _int++) {
                    BentFences.Entry entry = (BentFences.Entry)arrayList.get(_int);
                    if ((!_boolean || isoDirections == IsoDirections.Max || isoDirections == entry.dir) && this.isValidObject(isoObject, entry, _boolean)) {
                        return entry;
                    }
                }
            }

            return null;
        } else {
            return null;
        }
    }

    private boolean isValidObject(IsoObject isoObject, BentFences.Entry entry, boolean _boolean) {
        IsoCell isoCell = IsoWorld.instance.CurrentCell;
        ArrayList arrayList = _boolean ? entry.unbent : entry.bent;
        int int0 = ((String)arrayList.get(2)).equals(isoObject.sprite.name) ? 2 : (((String)arrayList.get(3)).equals(isoObject.sprite.name) ? 3 : -1);
        if (int0 == -1) {
            return false;
        } else {
            for (int int1 = 0; int1 < arrayList.size(); int1++) {
                int int2 = isoObject.square.x + (entry.isNorth() ? int1 - int0 : 0);
                int int3 = isoObject.square.y + (entry.isNorth() ? 0 : int1 - int0);
                IsoGridSquare isoGridSquare = isoCell.getGridSquare(int2, int3, isoObject.square.z);
                if (isoGridSquare == null) {
                    return false;
                }

                if (int0 != int1 && this.getObjectForEntry(isoGridSquare, arrayList, int1) == null) {
                    return false;
                }
            }

            return true;
        }
    }

    IsoObject getObjectForEntry(IsoGridSquare isoGridSquare, ArrayList<String> arrayList, int int1) {
        for (int int0 = 0; int0 < isoGridSquare.getObjects().size(); int0++) {
            IsoObject isoObject = isoGridSquare.getObjects().get(int0);
            if (isoObject.sprite != null && isoObject.sprite.name != null && ((String)arrayList.get(int1)).equals(isoObject.sprite.name)) {
                return isoObject;
            }
        }

        return null;
    }

    public void swapTiles(IsoObject obj, IsoDirections dir) {
        boolean _boolean = dir != null;
        BentFences.Entry entry = this.getEntryForObject(obj, dir);
        if (entry != null) {
            if (_boolean) {
                if (entry.isNorth() && dir != IsoDirections.N && dir != IsoDirections.S) {
                    return;
                }

                if (!entry.isNorth() && dir != IsoDirections.W && dir != IsoDirections.E) {
                    return;
                }
            }

            IsoCell isoCell = IsoWorld.instance.CurrentCell;
            ArrayList arrayList = _boolean ? entry.unbent : entry.bent;
            int int0 = ((String)arrayList.get(2)).equals(obj.sprite.name) ? 2 : (((String)arrayList.get(3)).equals(obj.sprite.name) ? 3 : -1);

            for (int int1 = 0; int1 < arrayList.size(); int1++) {
                int int2 = obj.square.x + (entry.isNorth() ? int1 - int0 : 0);
                int int3 = obj.square.y + (entry.isNorth() ? 0 : int1 - int0);
                IsoGridSquare isoGridSquare = isoCell.getGridSquare(int2, int3, obj.square.z);
                if (isoGridSquare != null) {
                    IsoObject isoObject = this.getObjectForEntry(isoGridSquare, arrayList, int1);
                    if (isoObject != null) {
                        String string = _boolean ? (String)entry.bent.get(int1) : (String)entry.unbent.get(int1);
                        IsoSprite isoSprite = IsoSpriteManager.instance.getSprite(string);
                        isoSprite.name = string;
                        isoObject.setSprite(isoSprite);
                        isoObject.transmitUpdatedSprite();
                        isoGridSquare.RecalcAllWithNeighbours(true);
                        zombie.MapCollisionData.instance.squareChanged(isoGridSquare);
                        PolygonalMap2.instance.squareChanged(isoGridSquare);
                        IsoRegions.squareChanged(isoGridSquare);
                    }
                }
            }
        }
    }

    public void bendFence(IsoObject obj, IsoDirections dir) {
        this.swapTiles(obj, dir);
    }

    public void unbendFence(IsoObject obj) {
        this.swapTiles(obj, null);
    }

    public void Reset() {
        this.m_entries.clear();
        this.m_bentMap.clear();
        this.m_unbentMap.clear();
    }

    private static final class Entry {
        IsoDirections dir = IsoDirections.Max;
        final ArrayList<String> unbent = new ArrayList();
        final ArrayList<String> bent = new ArrayList();

        boolean isNorth() {
            return this.dir == IsoDirections.N || this.dir == IsoDirections.S;
        }
    }
}
